using System;
using System.Collections.Generic;
using System.Linq;

namespace ExcelTemplateEngine.Infrastructure.Logging
{
    public class DefaultLogger : ITemplateEngineLogger
    {
        private readonly LogLevel _minLevel;
        private readonly string _categoryName;
        
        public DefaultLogger(string? categoryName = null, LogLevel minLevel = LogLevel.Information)
        {
            _categoryName = categoryName ?? "TemplateEngine";
            _minLevel = minLevel;
        }
        
        public void LogTrace(string message, params object[] args)
        {
            Log(LogLevel.Trace, message, args);
        }
        
        public void LogDebug(string message, params object[] args)
        {
            Log(LogLevel.Debug, message, args);
        }
        
        public void LogInformation(string message, params object[] args)
        {
            Log(LogLevel.Information, message, args);
        }
        
        public void LogWarning(string message, params object[] args)
        {
            Log(LogLevel.Warning, message, args);
        }
        
        public void LogError(string message, params object[] args)
        {
            Log(LogLevel.Error, message, args);
        }
        
        public void LogError(Exception exception, string message, params object[] args)
        {
            Log(LogLevel.Error, $"{string.Format(message, args)}\nException: {exception}");
        }
        
        public void LogCritical(string message, params object[] args)
        {
            Log(LogLevel.Critical, message, args);
        }
        
        public void LogCritical(Exception exception, string message, params object[] args)
        {
            Log(LogLevel.Critical, $"{string.Format(message, args)}\nException: {exception}");
        }
        
        public void LogPerformance(string operation, TimeSpan duration, Dictionary<string, object>? metrics = null)
        {
            var message = $"Performance: {operation} took {duration.TotalMilliseconds:F2}ms";
            if (metrics != null && metrics.Any())
            {
                var metricsStr = string.Join(", ", metrics.Select(kvp => $"{kvp.Key}={kvp.Value}"));
                message += $" | Metrics: {metricsStr}";
            }
            Log(LogLevel.Information, message);
        }
        
        public IDisposable BeginScope(string scopeName)
        {
            return new LogScope(this, scopeName);
        }
        
        private void Log(LogLevel level, string message, params object[] args)
        {
            if (level < _minLevel) return;
            
            string formattedMessage;
            try
            {
                formattedMessage = args?.Length > 0 ? string.Format(message, args) : message;
            }
            catch (FormatException)
            {
                // 如果格式化失败，直接使用原始消息
                formattedMessage = message;
            }
            
            var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
            var logEntry = $"[{timestamp}] [{level}] [{_categoryName}] {formattedMessage}";
            
            Console.WriteLine(logEntry);
            
            // 在实际项目中，这里可以写入文件或其他日志目标
        }
        
        private class LogScope : IDisposable
        {
            private readonly ITemplateEngineLogger _logger;
            private readonly string _scopeName;
            private readonly DateTime _startTime;
            
            public LogScope(ITemplateEngineLogger logger, string scopeName)
            {
                _logger = logger;
                _scopeName = scopeName;
                _startTime = DateTime.Now;
                _logger.LogDebug("Entering scope: {ScopeName}", scopeName);
            }
            
            public void Dispose()
            {
                var duration = DateTime.Now - _startTime;
                _logger.LogDebug("Exiting scope: {ScopeName} (Duration: {Duration}ms)", 
                    _scopeName, duration.TotalMilliseconds);
            }
        }
    }
}